// games/loveletter.js
// 情书（Love Letter）游戏逻辑

const LoveLetter = {
    // 卡牌定义：每个数字对应两张牌（共16张）
    CARD_DECK: [1, 1, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 8],
    
    // 卡牌名称
    CARD_NAMES: {
        1: '卫兵',
        2: '牧师',
        3: '男爵',
        4: '侍女',
        5: '王子',
        6: '国王',
        7: '伯爵夫人',
        8: '公主'
    },
    
    // 卡牌描述
    CARD_DESCRIPTIONS: {
        1: '猜测一名玩家的手牌，如果猜中且该牌不是卫兵，则该玩家出局',
        2: '查看一名玩家的手牌',
        3: '与一名玩家比较手牌数字，数字较小的玩家出局',
        4: '在下一个回合前，保护自己不受其他玩家的影响',
        5: '选择一名玩家（包括自己），该玩家弃掉手牌并抽取新牌',
        6: '与一名玩家交换手牌',
        7: '如果手牌中同时有伯爵夫人和王子或国王，必须打出伯爵夫人',
        8: '如果弃掉公主，立即出局'
    },

    startGame: (room, io) => {
        console.log(`[情书] 房间 ${room.id} 游戏开始！`);
        
        // 初始化游戏状态
        room.gameState = LoveLetter.initGameState(room);
        
        // 向所有玩家发送游戏开始信号
        room.players.forEach(player => {
            const playerSocket = io.sockets.sockets.get(player.id);
            if (playerSocket) {
                const playerState = LoveLetter.getPlayerState(room, player.id);
                const isFirstPlayer = player.id === room.gameState.currentPlayerId;
                
                playerSocket.emit('game_started', {
                    game: 'loveletter',
                    state: room.gameState,
                    playerState: playerState,
                    players: room.players
                });
                
                // 如果是第一个玩家，立即发送回合通知
                if (isFirstPlayer) {
                    setTimeout(() => {
                        playerSocket.emit('your_turn', {
                            playerState: playerState
                        });
                    }, 500);
                }
            }
        });
    },

    rejoinGame: (room, io, returnedSocketId) => {
        console.log(`[情书] 玩家 ${returnedSocketId} 重新加入房间 ${room.id}！`);
        
        const playerSocket = io.sockets.sockets.get(returnedSocketId);
        if (playerSocket && room.gameState && !room.gameState.isGameEnded) {
            const playerState = LoveLetter.getPlayerState(room, returnedSocketId);
            const isCurrentPlayer = returnedSocketId === room.gameState.currentPlayerId;
            
            playerSocket.emit('game_started', {
                game: 'loveletter',
                state: room.gameState,
                playerState: playerState,
                players: room.players
            });
            
            // 如果轮到该玩家，发送回合通知
            if (isCurrentPlayer && !playerState.isOut) {
                setTimeout(() => {
                    playerSocket.emit('your_turn', {
                        playerState: playerState
                    });
                }, 500);
            }
        }
    },

    initGameState: (room) => {
        // 创建牌堆（复制卡牌）
        const deck = [...LoveLetter.CARD_DECK];
        
        // 洗牌
        for (let i = deck.length - 1; i > 0; i--) {
            const j = Math.floor(Math.random() * (i + 1));
            [deck[i], deck[j]] = [deck[j], deck[i]];
        }
        
        // 移除一张牌（面朝下，不显示）
        const removedCard = deck.pop();
        
        // 给每个玩家发一张起始手牌
        const playerHands = {};
        room.players.forEach(player => {
            playerHands[player.id] = deck.length > 0 ? [deck.pop()] : [];
        });
        
        // 初始化玩家状态
        const playerStatus = {};
        room.players.forEach(player => {
            playerStatus[player.id] = {
                isOut: false,
                isProtected: false,
                lastCardPlayed: null
            };
        });
        
        return {
            gameType: 'loveletter',
            deck: deck, // 剩余牌堆
            removedCard: removedCard, // 移除的牌
            playerHands: playerHands, // 每个玩家的手牌
            playerStatus: playerStatus, // 玩家状态
            currentPlayerIndex: 0, // 当前回合的玩家索引
            currentPlayerId: room.players[0].id, // 当前回合的玩家ID
            waitingForAction: null, // 等待的动作类型（如 'choose_player', 'guess_card' 等）
            actionData: null, // 动作相关的数据
            isGameEnded: false,
            winner: null,
            lastAction: null // 记录上一个动作，用于显示
        };
    },

    getPlayerState: (room, playerId) => {
        // 返回只给特定玩家看到的信息
        return {
            hand: room.gameState.playerHands[playerId] || [],
            isMyTurn: room.gameState.currentPlayerId === playerId,
            isOut: room.gameState.playerStatus[playerId]?.isOut || false
        };
    },

    handleAction: (room, socket, io, actionData) => {
        const { action, data } = actionData;
        const gameState = room.gameState;
        
        // 检查游戏是否已结束
        if (gameState.isGameEnded) {
            return socket.emit('error', { message: '游戏已结束！' });
        }
        
        // 检查是否是当前玩家的回合
        if (gameState.currentPlayerId !== socket.id) {
            return socket.emit('error', { message: '还没到你的回合！' });
        }
        
        console.log(`[情书] 玩家 ${socket.id} 执行动作: ${action}`, data);
        
        switch (action) {
            case 'play_card':
                LoveLetter.handlePlayCard(room, socket, io, data);
                break;
            case 'choose_player':
                LoveLetter.handleChoosePlayer(room, socket, io, data);
                break;
            case 'guess_card':
                LoveLetter.handleGuessCard(room, socket, io, data);
                break;
            default:
                socket.emit('error', { message: '未知的动作！' });
        }
    },

    handlePlayCard: (room, socket, io, data) => {
        const gameState = room.gameState;
        const playerHand = gameState.playerHands[socket.id];
        
        // 检查玩家是否已出局
        if (gameState.playerStatus[socket.id].isOut) {
            return socket.emit('error', { message: '你已经出局了！' });
        }
        
        // 检查玩家是否被保护（侍女效果）
        if (gameState.playerStatus[socket.id].isProtected) {
            // 清除保护状态
            gameState.playerStatus[socket.id].isProtected = false;
        }
        
        // 检查玩家是否有手牌
        if (!playerHand || playerHand.length === 0) {
            return socket.emit('error', { message: '你没有手牌！' });
        }
        
        // 如果手牌只有一张，说明还没抽牌，先抽牌
        if (playerHand.length === 1) {
            if (gameState.deck.length > 0) {
                const drawnCard = gameState.deck.pop();
                playerHand.push(drawnCard);
                
                // 通知玩家抽到牌了
                const playerState = LoveLetter.getPlayerState(room, socket.id);
                socket.emit('card_drawn', {
                    playerState: playerState,
                    drawnCard: drawnCard
                });
                
                // 重新广播状态
                LoveLetter.broadcastGameState(room, io, {
                    type: 'card_drawn',
                    playerId: socket.id
                });
                return;
            } else {
                // 牌堆空了，游戏结束
                LoveLetter.endGameByDeckEmpty(room, io);
                return;
            }
        }
        
        const { cardIndex } = data; // 玩家选择要打出的牌的索引（0或1）
        
        if (cardIndex < 0 || cardIndex >= playerHand.length) {
            return socket.emit('error', { message: '无效的卡牌索引！' });
        }
        
        const playedCard = playerHand[cardIndex];
        const remainingCard = playerHand[1 - cardIndex]; // 保留的另一张牌
        
        // 检查是否必须出伯爵夫人（7）
        if (remainingCard === 7 && (playedCard === 5 || playedCard === 6)) {
            return socket.emit('error', { message: '你必须打出伯爵夫人（7）！' });
        }
        if (playedCard === 7 && (remainingCard === 5 || remainingCard === 6)) {
            // 必须出伯爵夫人，继续执行
        }
        
        // 检查是否打出公主（8）
        if (playedCard === 8) {
            // 打出公主立即出局，保存出局时的手牌（公主）
            gameState.playerStatus[socket.id].isOut = true;
            gameState.playerStatus[socket.id].eliminatedCard = playedCard; // 保存出局时的手牌
            gameState.playerHands[socket.id] = [remainingCard];
            
            // 广播玩家出局
            LoveLetter.broadcastGameState(room, io, {
                type: 'player_out',
                playerId: socket.id,
                reason: '打出公主'
            });
            
            // 检查游戏是否结束
            if (LoveLetter.checkGameEnd(room, io)) {
                return;
            }
            
            // 继续下一个玩家的回合
            LoveLetter.nextTurn(room, io);
            return;
        }
        
        // 移除打出的牌
        gameState.playerHands[socket.id] = [remainingCard];
        gameState.playerStatus[socket.id].lastCardPlayed = playedCard;
        
        // 根据卡牌效果执行相应动作
        const cardEffect = LoveLetter.getCardEffect(playedCard);
        
        if (cardEffect.requiresTarget) {
            // 检查可用目标
            const availableTargets = LoveLetter.getAvailableTargets(room, socket.id, playedCard);
            
            // 特殊处理：如果卡牌不能选择自己，且没有可用目标，直接弃牌
            // 王子(5)可以选择自己，所以至少自己是可以选择的
            if (playedCard !== 5 && availableTargets.length === 0) {
                // 没有可用目标，直接弃掉这张牌，不执行效果
                LoveLetter.broadcastGameState(room, io, {
                    type: 'card_discarded',
                    playerId: socket.id,
                    card: playedCard,
                    cardName: LoveLetter.CARD_NAMES[playedCard],
                    reason: '没有可用目标'
                });
                
                // 清除等待状态
                gameState.waitingForAction = null;
                gameState.actionData = null;
                
                // 下一个玩家的回合
                LoveLetter.nextTurn(room, io);
                return;
            }
            
            // 对于王子(5)，如果只有自己可选，直接对自己执行效果（不需要等待选择）
            if (playedCard === 5 && availableTargets.length === 1 && availableTargets[0].id === socket.id) {
                // 直接对自己使用王子效果
                LoveLetter.executeCardEffect(room, socket, io, playedCard, socket.id);
                return;
            }
            
            // 需要选择目标的卡牌，等待玩家选择
            gameState.waitingForAction = cardEffect.actionType;
            gameState.actionData = {
                playedCard: playedCard,
                cardIndex: cardIndex
            };
            
            // 通知玩家选择目标
            socket.emit('action_required', {
                action: cardEffect.actionType,
                playedCard: playedCard,
                cardName: LoveLetter.CARD_NAMES[playedCard],
                description: LoveLetter.CARD_DESCRIPTIONS[playedCard],
                availableTargets: availableTargets
            });
            
            // 广播卡牌打出信息（不透露具体是哪张牌）
            LoveLetter.broadcastGameState(room, io, {
                type: 'card_played',
                playerId: socket.id,
                waitingForAction: cardEffect.actionType
            });
        } else {
            // 不需要目标的卡牌，立即执行效果
            LoveLetter.executeCardEffect(room, socket, io, playedCard, null);
        }
    },

    handleChoosePlayer: (room, socket, io, data) => {
        const gameState = room.gameState;
        
        if (gameState.waitingForAction !== 'choose_player') {
            return socket.emit('error', { message: '当前不需要选择玩家！' });
        }
        
        const { targetPlayerId } = data;
        const playedCard = gameState.actionData.playedCard;
        
        // 验证目标玩家是否有效
        const targetPlayer = room.players.find(p => p.id === targetPlayerId);
        if (!targetPlayer) {
            return socket.emit('error', { message: '无效的目标玩家！' });
        }
        
        // 检查目标玩家是否出局或被保护
        if (gameState.playerStatus[targetPlayerId].isOut) {
            return socket.emit('error', { message: '该玩家已出局！' });
        }
        
        // 检查目标玩家是否被侍女保护（除了王子可以选择自己）
        if (gameState.playerStatus[targetPlayerId].isProtected && targetPlayerId !== socket.id) {
            return socket.emit('error', { message: '该玩家被侍女保护！' });
        }
        
        // 执行卡牌效果
        LoveLetter.executeCardEffect(room, socket, io, playedCard, targetPlayerId);
    },

    handleGuessCard: (room, socket, io, data) => {
        const gameState = room.gameState;
        
        if (gameState.waitingForAction !== 'guess_card') {
            return socket.emit('error', { message: '当前不需要猜测卡牌！' });
        }
        
        const { targetPlayerId, guessedCard } = data;
        const playedCard = gameState.actionData.playedCard;
        
        // 验证目标玩家
        const targetPlayer = room.players.find(p => p.id === targetPlayerId);
        if (!targetPlayer) {
            return socket.emit('error', { message: '无效的目标玩家！' });
        }
        
        if (gameState.playerStatus[targetPlayerId].isOut) {
            return socket.emit('error', { message: '该玩家已出局！' });
        }
        
        if (gameState.playerStatus[targetPlayerId].isProtected) {
            return socket.emit('error', { message: '该玩家被侍女保护！' });
        }
        
        // 检查猜测是否正确（卫兵效果）
        const targetHand = gameState.playerHands[targetPlayerId];
        if (targetHand && targetHand.length > 0 && targetHand[0] === guessedCard && guessedCard !== 1) {
            // 猜对了，目标玩家出局，保存出局时的手牌
            gameState.playerStatus[targetPlayerId].isOut = true;
            gameState.playerStatus[targetPlayerId].eliminatedCard = guessedCard; // 保存出局时的手牌
            gameState.playerHands[targetPlayerId] = [];
            
            LoveLetter.broadcastGameState(room, io, {
                type: 'guard_success',
                playerId: socket.id,
                targetPlayerId: targetPlayerId,
                guessedCard: guessedCard
            });
            
            // 检查游戏是否结束
            if (LoveLetter.checkGameEnd(room, io)) {
                return;
            }
        } else {
            // 猜错了
            LoveLetter.broadcastGameState(room, io, {
                type: 'guard_fail',
                playerId: socket.id,
                targetPlayerId: targetPlayerId,
                guessedCard: guessedCard
            });
        }
        
        // 清除等待状态
        gameState.waitingForAction = null;
        gameState.actionData = null;
        
        // 下一个玩家的回合
        LoveLetter.nextTurn(room, io);
    },

    executeCardEffect: (room, socket, io, card, targetPlayerId) => {
        const gameState = room.gameState;
        let actionResult = null;
        
        switch (card) {
            case 2: // 牧师 - 查看手牌
                const targetHand = gameState.playerHands[targetPlayerId];
                socket.emit('reveal_hand', {
                    playerId: targetPlayerId,
                    hand: targetHand
                });
                actionResult = {
                    type: 'priest',
                    playerId: socket.id,
                    targetPlayerId: targetPlayerId
                };
                break;
                
            case 3: // 男爵 - 比较手牌
                const myHand = gameState.playerHands[socket.id];
                const opponentHand = gameState.playerHands[targetPlayerId];
                if (myHand[0] < opponentHand[0]) {
                    gameState.playerStatus[socket.id].isOut = true;
                    gameState.playerStatus[socket.id].eliminatedCard = myHand[0]; // 保存出局时的手牌
                    gameState.playerHands[socket.id] = [];
                    actionResult = {
                        type: 'baron_compare',
                        winnerId: targetPlayerId,
                        loserId: socket.id,
                        myCard: myHand[0],
                        opponentCard: opponentHand[0]
                    };
                } else if (myHand[0] > opponentHand[0]) {
                    gameState.playerStatus[targetPlayerId].isOut = true;
                    gameState.playerStatus[targetPlayerId].eliminatedCard = opponentHand[0]; // 保存出局时的手牌
                    gameState.playerHands[targetPlayerId] = [];
                    actionResult = {
                        type: 'baron_compare',
                        winnerId: socket.id,
                        loserId: targetPlayerId,
                        myCard: myHand[0],
                        opponentCard: opponentHand[0]
                    };
                } else {
                    // 相等，没有人出局
                    actionResult = {
                        type: 'baron_compare',
                        winnerId: null,
                        loserId: null,
                        myCard: myHand[0],
                        opponentCard: opponentHand[0]
                    };
                }
                break;
                
            case 4: // 侍女 - 保护自己
                gameState.playerStatus[socket.id].isProtected = true;
                actionResult = {
                    type: 'handmaid',
                    playerId: socket.id
                };
                break;
                
            case 5: // 王子 - 弃掉手牌并抽取新牌
                const princeTarget = gameState.playerHands[targetPlayerId];
                if (princeTarget && princeTarget.length > 0) {
                    const discardedCard = princeTarget[0];
                    
                    // 如果弃掉的是公主，该玩家出局，保存出局时的手牌（公主）
                    if (discardedCard === 8) {
                        gameState.playerStatus[targetPlayerId].isOut = true;
                        gameState.playerStatus[targetPlayerId].eliminatedCard = discardedCard; // 保存出局时的手牌
                        gameState.playerHands[targetPlayerId] = [];
                        actionResult = {
                            type: 'prince_discard_princess',
                            playerId: socket.id,
                            targetPlayerId: targetPlayerId
                        };
                    } else {
                        // 抽取新牌
                        if (gameState.deck.length > 0) {
                            gameState.playerHands[targetPlayerId] = [gameState.deck.pop()];
                        } else {
                            gameState.playerHands[targetPlayerId] = [];
                        }
                        actionResult = {
                            type: 'prince_discard',
                            playerId: socket.id,
                            targetPlayerId: targetPlayerId,
                            discardedCard: discardedCard
                        };
                    }
                }
                break;
                
            case 6: // 国王 - 交换手牌
                const myHandKing = gameState.playerHands[socket.id];
                const opponentHandKing = gameState.playerHands[targetPlayerId];
                gameState.playerHands[socket.id] = opponentHandKing;
                gameState.playerHands[targetPlayerId] = myHandKing;
                actionResult = {
                    type: 'king_swap',
                    playerId: socket.id,
                    targetPlayerId: targetPlayerId
                };
                break;
        }
        
        // 广播动作结果
        if (actionResult) {
            LoveLetter.broadcastGameState(room, io, actionResult);
            
            // 检查游戏是否结束
            if (LoveLetter.checkGameEnd(room, io)) {
                return;
            }
        }
        
        // 清除等待状态
        gameState.waitingForAction = null;
        gameState.actionData = null;
        
        // 下一个玩家的回合
        LoveLetter.nextTurn(room, io);
    },

    getCardEffect: (card) => {
        switch (card) {
            case 1: // 卫兵
                return { requiresTarget: true, actionType: 'guess_card' };
            case 2: // 牧师
                return { requiresTarget: true, actionType: 'choose_player' };
            case 3: // 男爵
                return { requiresTarget: true, actionType: 'choose_player' };
            case 4: // 侍女
                return { requiresTarget: false };
            case 5: // 王子
                return { requiresTarget: true, actionType: 'choose_player' };
            case 6: // 国王
                return { requiresTarget: true, actionType: 'choose_player' };
            default:
                return { requiresTarget: false };
        }
    },

    getAvailableTargets: (room, playerId, card) => {
        const gameState = room.gameState;
        const targets = [];
        
        room.players.forEach(player => {
            // 不能选择自己（除了王子）
            if (player.id === playerId && card !== 5) {
                return;
            }
            
            // 不能选择已出局的玩家
            if (gameState.playerStatus[player.id].isOut) {
                return;
            }
            
            // 不能选择被保护的玩家（除了王子可以选择自己）
            if (gameState.playerStatus[player.id].isProtected && player.id !== playerId) {
                return;
            }
            
            targets.push({
                id: player.id,
                name: player.name
            });
        });
        
        return targets;
    },

    nextTurn: (room, io) => {
        const gameState = room.gameState;
        const activePlayers = room.players.filter(p => !gameState.playerStatus[p.id].isOut);
        
        if (activePlayers.length === 0) {
            return; // 游戏应该已经结束了
        }
        
        // 找到当前玩家的索引
        let currentIndex = activePlayers.findIndex(p => p.id === gameState.currentPlayerId);
        
        // 移动到下一个玩家
        currentIndex = (currentIndex + 1) % activePlayers.length;
        gameState.currentPlayerId = activePlayers[currentIndex].id;
        
        // 通知轮到下一个玩家（玩家在打出卡牌前需要先抽牌）
        const playerSocket = io.sockets.sockets.get(gameState.currentPlayerId);
        if (playerSocket) {
            const playerState = LoveLetter.getPlayerState(room, gameState.currentPlayerId);
            playerSocket.emit('your_turn', {
                playerState: playerState
            });
        }
        
        // 广播轮到下一个玩家
        LoveLetter.broadcastGameState(room, io, {
            type: 'turn_start',
            currentPlayerId: gameState.currentPlayerId
        });
    },

    checkGameEnd: (room, io) => {
        const gameState = room.gameState;
        const activePlayers = room.players.filter(p => !gameState.playerStatus[p.id].isOut);
        
        if (activePlayers.length === 1) {
            // 只剩一个玩家，该玩家获胜
            gameState.isGameEnded = true;
            gameState.winner = activePlayers[0].id;
            
            LoveLetter.broadcastGameEnd(room, io, {
                winner: activePlayers[0].id,
                reason: 'last_player'
            });
            
            return true;
        }
        
        if (gameState.deck.length === 0) {
            // 牌堆空了，手牌数字最大的获胜
            return LoveLetter.endGameByDeckEmpty(room, io);
        }
        
        return false;
    },

    endGameByDeckEmpty: (room, io) => {
        const gameState = room.gameState;
        const activePlayers = room.players.filter(p => !gameState.playerStatus[p.id].isOut);
        
        if (activePlayers.length === 0) {
            return false;
        }
        
        // 找到手牌数字最大的玩家
        let winner = activePlayers[0];
        let maxCard = gameState.playerHands[winner.id]?.[0] || 0;
        
        activePlayers.forEach(player => {
            const card = gameState.playerHands[player.id]?.[0] || 0;
            if (card > maxCard) {
                maxCard = card;
                winner = player;
            }
        });
        
        gameState.isGameEnded = true;
        gameState.winner = winner.id;
        
        LoveLetter.broadcastGameEnd(room, io, {
            winner: winner.id,
            reason: 'highest_card',
            allHands: activePlayers.reduce((acc, p) => {
                acc[p.id] = gameState.playerHands[p.id];
                return acc;
            }, {})
        });
        
        return true;
    },

    broadcastGameState: (room, io, actionResult) => {
        // 更新最后动作
        room.gameState.lastAction = actionResult;
        
        // 向所有玩家广播游戏状态更新
        room.players.forEach(player => {
            const playerSocket = io.sockets.sockets.get(player.id);
            if (playerSocket) {
                const playerState = LoveLetter.getPlayerState(room, player.id);
                playerSocket.emit('game_state_updated', {
                    state: room.gameState,
                    playerState: playerState,
                    actionResult: actionResult
                });
            }
        });
    },

    broadcastGameEnd: (room, io, endData) => {
        room.players.forEach(player => {
            const playerSocket = io.sockets.sockets.get(player.id);
            if (playerSocket) {
                playerSocket.emit('game_ended', {
                    winner: endData.winner,
                    reason: endData.reason,
                    allHands: endData.allHands || {},
                    state: room.gameState
                });
            }
        });
    }
};

module.exports = LoveLetter;

